/*
 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include "los_task.h"
#include "ohos_init.h"
#include "lz_hardware.h"
#include "e53_gesture_sensor.h"

/* E53模块中
 * UART0_RX_M0 -> GPIO0_B6
 * UART0_TX_M0 -> GPIO0_B7
 */
#define UART_ID                 0

#define CMD_DAT                 "\x5A\xA5\x07\x82\x10\x00\x00\x00\x00\x00"
#define CMD_LEN                 10

#define PICTURE_HEIGHT          800
#define PICTURE_NUM             4
#define POS_STEP                0x10

unsigned int uart_init(void)
{
    unsigned int ret;
    UartAttribute attr;

    LzUartDeinit(UART_ID);

    attr.baudRate = 115200;
    attr.dataBits = UART_DATA_BIT_8;
    attr.pad = FLOW_CTRL_NONE;
    attr.parity = UART_PARITY_NONE;
    attr.rxBlock = UART_BLOCK_STATE_NONE_BLOCK;
    attr.stopBits = UART_STOP_BIT_1;
    attr.txBlock = UART_BLOCK_STATE_NONE_BLOCK;

    // 使用UART0
    PinctrlSet(GPIO0_PB6, MUX_FUNC2, PULL_KEEP, DRIVE_LEVEL2);
    PinctrlSet(GPIO0_PB7, MUX_FUNC2, PULL_KEEP, DRIVE_LEVEL2);
    
    ret = LzUartInit(UART_ID, &attr);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
        return 1;
    }

    return 0;
}

void e53_gs_process(void *arg)
{
    unsigned int ret = 0;
    unsigned short flag = 0;
    
    unsigned int idx = 0;
    int pos = 0; 
    int pos_set = 0;
    int pos_start = 0;
    int pos_end = 0;

    unsigned char cmd[] = CMD_DAT;
    unsigned char cmd_str[CMD_LEN*3+1] = {0};

    e53_gs_init();
    uart_init();

    ret = LzUartWrite(UART_ID, cmd, CMD_LEN);
    if (ret != LZ_HARDWARE_SUCCESS)
    {
        printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
        return;
    }

    while (1)
    {
        ret = e53_gs_get_gesture_state(&flag);
        pos_set = 0;
        if (ret != 0)
        {
            printf("Get Gesture Statu: 0x%x\n", flag);
            if (flag & GES_UP)
            {
                printf("\tUp\n");
                if(idx<PICTURE_NUM) {
                    pos_set = 1;
                }
            }
            if (flag & GES_DOWM)
            {
                printf("\tDown\n");
                if(idx>0) {
                    pos_set = -1;
                }
            }
            if (flag & GES_LEFT)
            {
                printf("\tLeft\n");
            }
            if (flag & GES_RIGHT)
            {
                printf("\tRight\n");
            }
            if (flag & GES_FORWARD)
            {
                printf("\tForward\n");
            }
            if (flag & GES_BACKWARD)
            {
                printf("\tBackward\n");
            }
            if (flag & GES_CLOCKWISE)
            {
                printf("\tClockwise\n");
            }
            if (flag & GES_COUNT_CLOCKWISE)
            {
                printf("\tCount Clockwise\n");
            }
            if (flag & GES_WAVE)
            {
                printf("\tWave\n");
            }
            
            e53_gs_led_up_set((flag & GES_UP) ? (1) : (0));
            e53_gs_led_down_set((flag & GES_DOWM) ? (1) : (0));
            e53_gs_led_left_set((flag & GES_LEFT) ? (1) : (0));
            e53_gs_led_right_set((flag & GES_RIGHT) ? (1) : (0));
            e53_gs_led_forward_set((flag & GES_FORWARD) ? (1) : (0));
            e53_gs_led_backward_set((flag & GES_BACKWARD) ? (1) : (0));
            e53_gs_led_cw_set((flag & GES_CLOCKWISE) ? (1) : (0));
            e53_gs_led_ccw_set((flag & GES_COUNT_CLOCKWISE) ? (1) : (0));
            e53_gs_led_wave_set((flag & GES_WAVE) ? (1) : (0));

            if(pos_set!=0) {
                if(pos_set==1 && idx<PICTURE_NUM) {
                    printf("%s, %d: uart write UP, idx: %02X\n", __FILE__, __LINE__, idx);
                    pos_start = PICTURE_HEIGHT * idx;
                    pos_end = PICTURE_HEIGHT * (idx+1);
                    for(pos=pos_start;pos<=pos_end;pos+=POS_STEP) {
                        cmd[CMD_LEN-2] = (pos/0x100) & 0xFF;
                        cmd[CMD_LEN-1] = (pos%0x100) & 0xFF;
                        for(int i=0;i<CMD_LEN;i++) {
                            sprintf(cmd_str+i*3, "%02X ", cmd[i] & 0xFF);
                        }
                        printf("DOWN HEX[%04d]: %s", pos, cmd_str);

                        ret = LzUartWrite(UART_ID, cmd, CMD_LEN);
                        if (ret != LZ_HARDWARE_SUCCESS)
                        {
                            printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
                        }
                    }
                    idx++;
                }

                if(pos_set==-1 && idx>0) {
                    printf("%s, %d: uart write DOWN, idx: %02X\n", __FILE__, __LINE__, idx);
                    pos_start = PICTURE_HEIGHT * idx;
                    pos_end = PICTURE_HEIGHT * (idx-1);
                    for(pos=pos_start;pos>=pos_end;pos-=POS_STEP) {
                        cmd[CMD_LEN-2] = (pos/0x100) & 0xFF;
                        cmd[CMD_LEN-1] = (pos%0x100) & 0xFF;
                        for(int i=0;i<CMD_LEN;i++) {
                            sprintf(cmd_str+i*3, "%02X ", cmd[i] & 0xFF);
                        }
                        printf("DOWN HEX[%04d]: %s", pos, cmd_str);

                        ret = LzUartWrite(UART_ID, cmd, CMD_LEN);
                        if (ret != LZ_HARDWARE_SUCCESS)
                        {
                            printf("%s, %d: LzUartInit(%d) failed!\n", __FILE__, __LINE__, ret);
                        }
                    }
                    idx--;
                }
            }
        }
        else
        {
            /* 如果没有数据，则多等待 */
            LOS_Msleep(50);
        }
    }
}

void e53_gs_example()
{
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    unsigned int ret = LOS_OK;

    task.pfnTaskEntry = (TSK_ENTRY_FUNC)e53_gs_process;
    task.uwStackSize = 2048;
    task.pcName = "e53 getsture sensor process";
    task.usTaskPrio = 24;
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK)
    {
        printf("Falied to create Task_One ret:0x%x\n", ret);
        return;
    }
}

APP_FEATURE_INIT(e53_gs_example);
